package com.mytrip.aop;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import com.mytrip.base.action.StrutsActionAdapter;
import com.mytrip.base.annotation.WriteMethod;
import com.mytrip.base.aop.BaseAspect;
import com.mytrip.base.exception.BaseException;
import com.mytrip.model.Module;
import com.mytrip.model.RoleModule;
import com.mytrip.service.ModuleManager;
import com.mytrip.util.BeanUtil;

@Aspect
public class ActionAccessAspect extends BaseAspect {

	private List<String> actionAccessExcludeList = new ArrayList<String>(0);
	
	private ModuleManager moduleManager;
	
	public void setModuleManager(ModuleManager moduleManager) {
		this.moduleManager = moduleManager;
	}

	public void setActionAccessExcludeList(List<String> actionAccessExcludeList) {
		this.actionAccessExcludeList = actionAccessExcludeList;
	}

	// ~ method ==================================================================
	
	@Pointcut("execution(* com.mytrip.webapp.action..*Action.*(..)) " +
				"&& !execution(* com.mytrip.webapp.action..*Action.get*(..)) " +
				"&& !execution(* com.mytrip.webapp.action..*Action.set*(..))")
	public void actionSecurityPt() {
	}

	@Around("actionSecurityPt() && target(action)")
	public Object securityAccess(ProceedingJoinPoint pjp, StrutsActionAdapter action)
			throws Throwable {
		Method method = ((MethodSignature) pjp.getSignature()).getMethod();	
		String shortName = BeanUtil.extractLShortName(action.getClass());
		
		for(String aopAccessExcludeActionName :  actionAccessExcludeList){
			if (aopAccessExcludeActionName.equals(shortName)){
				return pjp.proceed();
			}			
		}		
		
		Map<String, RoleModule> roleModuleMap = action.getSessionBag().getRoleModuleMap();
		RoleModule rmodule = roleModuleMap.get(shortName);

		if (rmodule != null){
			if (method.isAnnotationPresent(WriteMethod.class) 
					&& rmodule.getModuleReadWrite() != RoleModule.MODULE_WRITE){
				Module module = moduleManager.getModuleByActionName(shortName);
				throw new BaseException("W0000026", new String[]{module.getModuleName()});  
			}
		} else {
			Module module = moduleManager.getModuleByActionName(shortName);
			throw new BaseException("W0000002", new String[]{module==null?"unregister module :"+shortName:module.getModuleName()});
		}
		
		return pjp.proceed();
	}

}
